package gowebdav

import (
	"bytes"
	"encoding/json"
	"fmt"
	"gopp"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/cookiejar"
	"net/url"
	"path/filepath"
	"strings"
	"time"

	simplejson "github.com/bitly/go-simplejson"
	"github.com/clbanning/mxj"
	"golang.org/x/net/publicsuffix"
)

var baseuri = "http://oci.fixlan.tk:443"
var davuri = fmt.Sprintf("%s/remote.php/dav", baseuri)
var bmuri = fmt.Sprintf("%s/apps/bookmarks/bookmark", baseuri)
var rssuri = fmt.Sprintf("%s/apps/news/feeds", baseuri)
var noteuri = fmt.Sprintf("%s/apps/notes/notes", baseuri)
var taskuri = fmt.Sprintf("%s/calendars/%s", davuri, username)
var deckuri = fmt.Sprintf("%s/apps/deck/boards", davuri)

func (this *Client2) AddBookMark(link string, tags []string) (string, error) {
	bm := url.Values{}
	bm.Add("url", link)
	bm.Add("title", "title")
	bm.Add("from_own", "0")
	bm.Add("description", "ddd")
	bm.Add("added_date", time.Now().String())

	body := bytes.NewBufferString(bm.Encode())
	resp, err := this.reqapp("POST", bmuri, body, func(r *http.Request) { this.fixWebHeader(r, CCTY_FORM) })
	if false {
		log.Println(resp.StatusCode, resp.Status, resp.Header)
	}
	bcc, err1 := ioutil.ReadAll(resp.Body)
	log.Println(err1, string(bcc))
	if err != nil {
		log.Println(resp, bmuri, bm.Encode())
	}
	var bmid string = ""
	switch resp.StatusCode {
	case 200:
		jso, err2 := simplejson.NewJson(bcc)
		err = err2
		bmid = jso.Get("item").Get("id").MustString()
	default:
		err = fmt.Errorf("%s", resp.Status)
		log.Println(err, link)
	}
	return bmid, err

}

func (this *Client2) DeleteBookmark(bmid string) error {
	if bmid == "" {
		return fmt.Errorf("empty id")
	}

	u := fmt.Sprintf("%s/%s", bmuri, bmid)
	resp, err := this.reqapp("DELETE", u, nil, func(r *http.Request) { this.fixWebHeader(r, CCTY_EMPTY) })
	bcc, err1 := ioutil.ReadAll(resp.Body)
	if false {
		log.Println(err1, string(bcc))
	}
	// log.Println(resp.StatusCode, resp.Status, resp.Header)
	switch resp.StatusCode {
	case 200:
	default:
		err = fmt.Errorf("%s", resp.Status)
		log.Println(err, bmid)
	}
	return err
}

func (this *Client2) ListBookmark(pageno int) (bmids []string, err error) {
	u := fmt.Sprintf("%s%s", bmuri, "?type=bookmark&tag=&page=0&conjunction=and&sort=bookmarks_sorting_recent")
	resp, err := this.reqapp("GET", u, nil, func(r *http.Request) { this.fixWebHeader(r, CCTY_EMPTY) })
	bcc, err1 := ioutil.ReadAll(resp.Body)
	if false {
		log.Println(err1, string(bcc))
		log.Println(resp.StatusCode, resp.Status, resp.Header)
	}
	switch resp.StatusCode {
	case 200:
		jso, err1 := simplejson.NewJson(bcc)
		err = err1
		djso := jso.Get("data")
		for i, _ := range djso.MustArray() {
			id := djso.GetIndex(i).Get("id").MustString()
			bmids = append(bmids, id)
		}
	default:
		err = fmt.Errorf("%s", resp.Status)
		log.Println(err)
	}
	return
}

func (this *Client2) AddFeed(link string) (id string, err error) {
	u := rssuri

	pdata := map[string]string{
		"parentFolderId": "0",
		"url":            link,
		"user":           "", "password": "",
	}

	bcc, err := json.Marshal(pdata)
	body := bytes.NewBuffer(bcc)
	resp, err := this.reqapp("POST", u, body, func(r *http.Request) { this.fixWebHeader(r, CCTY_JSON) })
	bcc, err1 := ioutil.ReadAll(resp.Body)
	if true {
		log.Println(err1, string(bcc))
		log.Println(resp.StatusCode, resp.Status, resp.Header)
	}
	switch resp.StatusCode {
	case 200:
		// {"feeds":[{"id":31,"userId":"synctu","urlHash":"cd1ed788409faa7dbc41a5e200a2cbbc","url":"https:\/\/stackoverflow.com\/feeds\/question\/24940803","title":"Owncloud webdav access from php - Stack Overflow","faviconLink":"https:\/\/cdn.sstatic.net\/Sites\/stackoverflow\/img\/favicon.ico?v=4f32ecc8f43d","added":1521991301,"folderId":0,"unreadCount":2,"link":"https:\/\/stackoverflow.com\/q\/24940803","preventUpdate":null,"deletedAt":null,"articlesPerUpdate":2,"location":"https:\/\/stackoverflow.com\/feeds\/question\/24940803","ordering":null,"fullTextEnabled":null,"pinned":null,"updateMode":null,"updateErrorCount":null,"lastUpdateError":null,"basicAuthUser":null,"basicAuthPassword":null,"cssClass":"custom-stackoverflow-com"}],"newestItemId":656}
		jso, err1 := simplejson.NewJson(bcc)
		err = err1
		id = fmt.Sprintf("%v", jso.Get("feeds").GetIndex(0).Get("id").Interface())
	default:
		err = fmt.Errorf("%s: %s", resp.Status, link)
		log.Println(err)
	}
	return
}

func (this *Client2) DeleteFeed(id string) (err error) {
	if id == "" {
		return fmt.Errorf("empty id")
	}
	u := fmt.Sprintf("%s/%s", rssuri, id)

	resp, err := this.reqapp("DELETE", u, nil, func(r *http.Request) { this.fixWebHeader(r, CCTY_JSON) })
	bcc, err1 := ioutil.ReadAll(resp.Body)
	if false {
		log.Println(err1, string(bcc))
		log.Println(resp.StatusCode, resp.Status, resp.Header)
	}
	switch resp.StatusCode {
	case 200:
		// []
	default:
		err = fmt.Errorf("%s: %s", resp.Status, id)
		log.Println(err)
	}
	return
}

func (this *Client2) ListFeed() (ids []string, err error) {
	u := fmt.Sprintf("%s", rssuri)

	resp, err := this.reqapp("GET", u, nil, func(r *http.Request) { this.fixWebHeader(r, CCTY_JSON) })
	bcc, err1 := ioutil.ReadAll(resp.Body)
	if false {
		log.Println(err1, string(bcc))
		log.Println(resp.StatusCode, resp.Status, resp.Header)
	}
	switch resp.StatusCode {
	case 200:
		// {"feeds":[{"id":37,"userId":"synctu","urlHash":"4e82c2b8fc951be127894aa71de5b764","url":"https:\/\/planet.kde.org\/rss20.xml","title":"Planet KDE","faviconLink":"http:\/\/planetKDE.org\/favicon.ico","added":1521992929,"folderId":0,"unreadCount":25,"link":"http:\/\/planetKDE.org\/","preventUpdate":false,"deletedAt":0,"articlesPerUpdate":25,"location":"https:\/\/planet.kde.org\/rss20.xml","ordering":0,"fullTextEnabled":false,"pinned":false,"updateMode":0,"updateErrorCount":0,"lastUpdateError":null,"basicAuthUser":"","basicAuthPassword":"","cssClass":"custom-planetKDE-org"}],"starred":0,"newestItemId":803}
		jso, err1 := simplejson.NewJson(bcc)
		err = err1
		djso := jso.Get("feeds")
		for i, _ := range djso.MustArray() {
			id := fmt.Sprintf("%v", djso.GetIndex(i).Get("id").Interface())
			ids = append(ids, id)
		}
	default:
		err = fmt.Errorf("%s", resp.Status)
		log.Println(err)
	}
	return
}

func (this *Client2) AddNote(content string, title string) (id string, err error) {
	u := noteuri

	pdata := map[string]string{}
	bcc, err := json.Marshal(pdata)
	body := bytes.NewBuffer(bcc)
	resp, err := this.reqapp("POST", u, body, func(r *http.Request) { this.fixWebHeader(r, CCTY_JSON) })
	bcc, err1 := ioutil.ReadAll(resp.Body)
	if true {
		log.Println(err1, string(bcc))
		log.Println(resp.StatusCode, resp.Status, resp.Header)
	}
	switch resp.StatusCode {
	case 200:
		// {"etag":"1f84be9a25bb3ae271cefa0eca98ca0a","modified":1521993533,"title":"\u65b0\u5efa\u7b14\u8bb0 (3)","category":null,"content":"","favorite":false,"id":59502}
		jso, err1 := simplejson.NewJson(bcc)
		err = err1
		id = fmt.Sprintf("%v", jso.Get("id").Interface())
		etag := jso.Get("etag").MustString()
		err = this.UpdateNote(id, content, title, etag)
	default:
		err = fmt.Errorf("%s: %s", resp.Status, title)
		log.Println(err)
	}
	return
}

func (this *Client2) UpdateNote(id string, content string, title, etag string) (err error) {
	u := fmt.Sprintf("%s/%s", noteuri, id)

	//{"etag":"e43405892c23652c615339e1783373de","modified":1521993604,"title":"uuuuuu","category":null,"content":"uuuuuu\n\n\n","favorite":false,"id":59500}
	pdata := map[string]interface{}{"etag": etag, "title": title, "category": "",
		"content": content, "modified": time.Now().Unix()}
	bcc, err := json.Marshal(pdata)
	body := bytes.NewBuffer(bcc)
	resp, err := this.reqapp("PUT", u, body, func(r *http.Request) { this.fixWebHeader(r, CCTY_JSON) })
	bcc, err1 := ioutil.ReadAll(resp.Body)
	if true {
		log.Println(err1, string(bcc))
		log.Println(resp.StatusCode, resp.Status, resp.Header)
	}
	switch resp.StatusCode {
	case 200:
		// {"etag":"1f84be9a25bb3ae271cefa0eca98ca0a","modified":1521993533,"title":"\u65b0\u5efa\u7b14\u8bb0 (3)","category":null,"content":"","favorite":false,"id":59502}
		jso, err1 := simplejson.NewJson(bcc)
		err = err1
		id = fmt.Sprintf("%v", jso.Get("id").Interface())
	default:
		err = fmt.Errorf("%s: %s", resp.Status, title)
		log.Println(err)
	}
	return
}

func (this *Client2) DeleteNote(id string) (err error) {
	if id == "" {
		return fmt.Errorf("empty id")
	}
	u := fmt.Sprintf("%s/%s", noteuri, id)

	resp, err := this.reqapp("DELETE", u, nil, func(r *http.Request) { this.fixWebHeader(r, CCTY_JSON) })
	bcc, err1 := ioutil.ReadAll(resp.Body)
	if false {
		log.Println(err1, string(bcc))
		log.Println(resp.StatusCode, resp.Status, resp.Header)
	}
	switch resp.StatusCode {
	case 200:
		// []
	default:
		err = fmt.Errorf("%s: %s", resp.Status, id)
		log.Println(err)
	}
	return
}

func (this *Client2) ListNote() (ids []string, err error) {
	u := fmt.Sprintf("%s", noteuri)

	resp, err := this.reqapp("GET", u, nil, func(r *http.Request) { this.fixWebHeader(r, CCTY_JSON) })
	bcc, err1 := ioutil.ReadAll(resp.Body)
	if false {
		log.Println(err1, string(bcc))
		log.Println(resp.StatusCode, resp.Status, resp.Header)
	}
	switch resp.StatusCode {
	case 200:
		// [{"etag":"224abbbc232509c20b6e76cd2934f2c2","modified":1521994302,"title":"hehecc","category":null,"content":"hehecc","favorite":false,"id":59506},{"etag":"7878114e51add5883454aaee0828147c","modified":1521993645,"title":"uuuuuu","category":null,"content":"uuuuuu\n\n\njjjjkk","favorite":false,"id":59500},{"etag":"3f684250228cab1eec9acb7b6c2c73cc","modified":1521993527,"title":"\u65b0\u5efa\u7b14\u8bb0 (2)","category":null,"content":"","favorite":false,"id":59501},{"etag":"1f84be9a25bb3ae271cefa0eca98ca0a","modified":1521993533,"title":"\u65b0\u5efa\u7b14\u8bb0 (3)","category":null,"content":"","favorite":false,"id":59502}]
		jso, err1 := simplejson.NewJson(bcc)
		err = err1
		for i, _ := range jso.MustArray() {
			id := fmt.Sprintf("%v", jso.GetIndex(i).Get("id").Interface())
			ids = append(ids, id)
		}
	default:
		err = fmt.Errorf("%s", resp.Status)
		log.Println(err)
	}
	return
}

func (this *Client2) AddTaskList(name string) (err error) {
	u := fmt.Sprintf("%s/%s/", taskuri, name)

	body_tpl := `<c:mkcalendar xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:" xmlns:a="http://apple.com/ns/ical/" xmlns:o="http://owncloud.org/ns">
    <d:set>
        <d:prop>
            <d:displayname>%s</d:displayname>
            <o:calendar-enabled>1</o:calendar-enabled>
            <a:calendar-color>#31CC7C</a:calendar-color>
            <c:supported-calendar-component-set>
                <c:comp name="VTODO"/></c:supported-calendar-component-set>
            </d:prop>
        </d:set>
        </c:mkcalendar>`
	body_str := fmt.Sprintf(body_tpl, name)
	body := bytes.NewBufferString(body_str)

	resp, err := this.reqapp("MKCALENDAR", u, body, func(r *http.Request) { this.fixWebHeader(r, CCTY_XML) })
	bcc, err1 := ioutil.ReadAll(resp.Body)
	if true {
		log.Println(err1, string(bcc))
		log.Println(resp.StatusCode, resp.Status, resp.Header)
	}
	switch resp.StatusCode {
	case 200:
	default:
		err = fmt.Errorf("%s: %s", resp.Status, name)
		log.Println(err)
	}

	return
}

func (this *Client2) RenameTaskList(name string, newname string) (err error) {
	u := fmt.Sprintf("%s/%s/", taskuri, name)

	body_tpl := `<d:propertyupdate xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:" xmlns:a="http://apple.com/ns/ical/" xmlns:o="http://owncloud.org/ns">
    <d:set>
        <d:prop>
            <d:displayname>%s</d:displayname>
            </d:prop>
            </d:set>
            </d:propertyupdate>`
	body_str := fmt.Sprintf(body_tpl, newname)
	body := bytes.NewBufferString(body_str)

	resp, err := this.reqapp("PROPPATCH", u, body, func(r *http.Request) { this.fixWebHeader(r, CCTY_XML) })
	bcc, err1 := ioutil.ReadAll(resp.Body)
	if true {
		log.Println(err1, string(bcc))
		log.Println(resp.StatusCode, resp.Status, resp.Header)
	}
	switch resp.StatusCode {
	case 200:
	default:
		err = fmt.Errorf("%s: %s", resp.Status, name)
		log.Println(err)
	}

	return
}

func (this *Client2) ListTaskList() (names []string, err error) {
	u := fmt.Sprintf("%s/", taskuri)

	body_tpl := `<?xml version="1.0"?>
<d:propfind  xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:aapl="http://apple.com/ns/ical/" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.com/ns" xmlns:cs="http://calendarserver.org/ns/">
  <d:prop>
    <d:displayname />
    <c:calendar-description />
    <c:calendar-timezone />
    <aapl:calendar-order />
    <aapl:calendar-color />
    <c:supported-calendar-component-set />
    <oc:calendar-enabled />
    <d:acl />
    <d:owner />
    <oc:invite />
  </d:prop>
</d:propfind>`
	body_str := fmt.Sprintf(body_tpl)
	body := bytes.NewBufferString(body_str)

	resp, err := this.reqapp("PROPFIND", u, body, func(r *http.Request) { this.fixWebHeader(r, CCTY_XML) })
	bcc, err1 := ioutil.ReadAll(resp.Body)
	if false {
		log.Println(err1, string(bcc))
		log.Println(resp.StatusCode, resp.Status, resp.Header)
	}
	switch resp.StatusCode {
	case 200:
	case 207:
		mx, err1 := mxj.NewMapXml(bcc)
		jcc, err2 := mx.Json()
		jso, err3 := simplejson.NewJson(jcc)
		log.Println(err1, err2, err3)
		ioutil.WriteFile("task_list_res.json", jcc, 0644)
		rjso := jso.Get("multistatus").Get("response")
		for i, _ := range rjso.MustArray() {
			href := rjso.GetIndex(i).Get("href").MustString()
			if !strings.HasSuffix(href, fmt.Sprintf("/dav/calendars/%s/", username)) {
				rname := strings.Split(href, fmt.Sprintf("/%s/", username))[1]
				rname = strings.Trim(rname, "/")
				names = append(names, rname)
			}
		}
	default:
		err = fmt.Errorf("%s", resp.Status)
		log.Println(err)
	}

	return
}

func (this *Client2) DeleteTaskList(name string) (err error) {
	if name == "" {
		return fmt.Errorf("empty name")
	}
	u := fmt.Sprintf("%s/%s", taskuri, name)
	resp, err := this.reqapp("DELETE", u, nil, func(r *http.Request) { this.fixWebHeader(r, CCTY_HTML) })
	bcc, err1 := ioutil.ReadAll(resp.Body)
	if false {
		log.Println(err1, string(bcc))
		log.Println(resp.StatusCode, resp.Status, resp.Header)
	}
	switch resp.StatusCode {
	case 200:
	case 204:
	default:
		err = fmt.Errorf("%s", resp.Status)
		log.Println(err)
	}

	return
}

// TODO sub task
func (this *Client2) AddTask(name string, title string) (err error) {
	if true {
		id := gopp.RandomStringAlphaLowerDigit(21)
		return this.UpdateTask(name, title, id)
	}
	u := fmt.Sprintf("%s/%s/%s", taskuri, name, "Nextcloud-o3wbtutzbi63l61jrhv84.ics")
	body_tpl := `BEGIN:VCALENDAR
PRODID:-//Nextcloud Tasks v0.9.5
BEGIN:VTODO
CREATED:20180325T171538
DTSTAMP:20180325T171538
LAST-MODIFIED:20180325T171538
UID:%s
SUMMARY:%s
PRIORITY:0
PERCENT-COMPLETE:0
X-OC-HIDESUBTASKS:0
END:VTODO
END:VCALENDAR`
	body_str := fmt.Sprintf(body_tpl, gopp.RandomStringAlphaLowerDigit(10), title)
	body := bytes.NewBufferString(body_str)

	resp, err := this.reqapp("PUT", u, body, func(r *http.Request) { this.fixWebHeader(r, CCTY_CALENDER) })
	bcc, err1 := ioutil.ReadAll(resp.Body)
	if false {
		log.Println(err1, string(bcc))
		log.Println(resp.StatusCode, resp.Status, resp.Header)
	}
	switch resp.StatusCode {
	case 200:
	case 204:
	default:
		err = fmt.Errorf("%s: %s, %s", resp.Status, name, title)
		log.Println(err)
	}

	return
}

func (this *Client2) UpdateTask(name string, title string, id string) (err error) {
	u := fmt.Sprintf("%s/%s/%s", taskuri, name, fmt.Sprintf("Nextcloud-%s.ics", id))
	body_tpl := `BEGIN:VCALENDAR
PRODID:-//Nextcloud Tasks v0.9.5
BEGIN:VTODO
CREATED:20180325T171538
DTSTAMP:20180325T171538
LAST-MODIFIED:20180325T171538
UID:%s
SUMMARY:%s
PRIORITY:0
PERCENT-COMPLETE:0
X-OC-HIDESUBTASKS:0
END:VTODO
END:VCALENDAR`
	body_str := fmt.Sprintf(body_tpl, gopp.RandomStringAlphaLowerDigit(10), title)
	body := bytes.NewBufferString(body_str)

	resp, err := this.reqapp("PUT", u, body, func(r *http.Request) { this.fixWebHeader(r, CCTY_CALENDER) })
	bcc, err1 := ioutil.ReadAll(resp.Body)
	if false {
		log.Println(err1, string(bcc))
		log.Println(resp.StatusCode, resp.Status, resp.Header)
	}
	switch resp.StatusCode {
	case 200:
	case 204:
	default:
		err = fmt.Errorf("%s: %s, %s", resp.Status, name, title)
		log.Println(err)
	}

	return
}

func (this *Client2) DeleteTask(name string, title string) (err error) {
	if name == "" {
		return fmt.Errorf("empty name")
	}
	u := fmt.Sprintf("%s/%s/%s", taskuri, name, "Nextcloud-o3wbtutzbi63l61jrhv84.ics")
	resp, err := this.reqapp("DELETE", u, nil, func(r *http.Request) { this.fixWebHeader(r, CCTY_HTML) })
	bcc, err1 := ioutil.ReadAll(resp.Body)
	if false {
		log.Println(err1, string(bcc))
		log.Println(resp.StatusCode, resp.Status, resp.Header)
	}
	switch resp.StatusCode {
	case 200:
	case 204:
	default:
		err = fmt.Errorf("%s", resp.Status)
		log.Println(err)
	}

	return
}

func (this *Client2) ListTask(name string) (ids []string, err error) {
	u := fmt.Sprintf("%s/%s/", taskuri, name)

	body_tpl := `<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:a="http://apple.com/ns/ical/" xmlns:d="DAV:" xmlns:o="http://owncloud.org/ns">
   <d:prop>
      <d:getetag />
      <c:calendar-data />
   </d:prop>
   <c:filter>
      <c:comp-filter name="VCALENDAR">
         <c:comp-filter name="VTODO">
            <c:prop-filter name="COMPLETED">
               <c:is-not-defined />
            </c:prop-filter>
         </c:comp-filter>
      </c:comp-filter>
   </c:filter>
</c:calendar-query>`
	body_str := fmt.Sprintf(body_tpl)
	body := bytes.NewBufferString(body_str)

	resp, err := this.reqapp("REPORT", u, body, func(r *http.Request) {
		r.Header.Add("Depth", "1")
		this.fixWebHeader(r, CCTY_XML)
	})
	bcc, err1 := ioutil.ReadAll(resp.Body)
	if false {
		log.Println(err1, string(bcc))
		log.Println(resp.StatusCode, resp.Status, resp.Header)
	}
	switch resp.StatusCode {
	case 200:
	case 207:
		mx, err1 := mxj.NewMapXml(bcc)
		jcc, err2 := mx.Json()
		jso, err3 := simplejson.NewJson(jcc)
		log.Println(err1, err2, err3)
		ioutil.WriteFile("task_res.json", jcc, 0644)
		rjso := jso.Get("multistatus").Get("response")
		for i, _ := range rjso.MustArray() {
			href := rjso.GetIndex(i).Get("href").MustString()
			rname := strings.Split(filepath.Base(href), "Nextcloud-")[1]
			rname = rname[:len(rname)-4] // trim .ics
			ids = append(ids, rname)
		}
	case 400:
		mx, _ := mxj.NewMapXml(bcc)
		jcc, _ := mx.Json()
		jso, err3 := simplejson.NewJson(jcc)
		err = err3
		err = fmt.Errorf("%s: %s", resp.Status, jso.Get("error").Get("message").MustString())
	default:
		err = fmt.Errorf("%s", resp.Status)
		log.Println(err)
	}
	return
}

func (this *Client2) fixWebHeader(r *http.Request, ctype string) {
	if ctype != "" {
		r.Header.Add("Content-Type", ctype)
	}
	r.Header.Add("OCS-APIREQUEST", "true")
	r.Header.Add("Origin", baseuri)
	r.Header.Add("DNT", "1")
	r.Header.Add("requesttoken", this.requesttoken)
}

const CCTY_EMPTY = ""
const CCTY_HTML = "text/html; charset=UTF-8"
const CCTY_FORM = "application/x-www-form-urlencoded; charset=UTF-8"
const CCTY_JSON = "application/json;charset=UTF-8"
const CCTY_XML = "application/xml; charset=UTF-8"
const CCTY_CALENDER = "text/calendar; charset=UTF-8"

///
type Client2 struct {
	*Client

	requesttoken string
}

func NewClient2(uri string, user string, pw string) *Client2 {
	this := &Client2{}
	this.Client = NewClient(uri, user, pw)
	this.Client.c.Jar, _ = cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
	return this
}

func (c *Client2) Connect() (err error) {
	err = c.Client.Connect()
	if err == nil {
		c.weblogin()
	}
	return err
}

func (c *Client2) weblogin() {
	u := fmt.Sprintf("%s/login", baseuri)
	resp, err := c.reqapp("GET", u, nil, nil)
	log.Println(err)
	bcc, err := ioutil.ReadAll(resp.Body)
	// log.Println(string(bcc))
	lines := strings.Split(string(bcc), "\n")
	for _, line := range lines {
		if strings.Contains(line, "data-requesttoken=") {
			c.requesttoken = strings.Split(line, "\"")[5]
			log.Println(c.requesttoken)
		}
	}
}

func (c *Client2) reqapp(method string, uri string, body io.Reader, intercept func(*http.Request)) (req *http.Response, err error) {
	return c.Client.reqapp(method, uri, body, intercept)
}

func (c *Client) reqapp(method string, uri string, body io.Reader, intercept func(*http.Request)) (req *http.Response, err error) {

	log.Println(method, uri)
	r, err := http.NewRequest(method, uri, body)
	if err != nil {
		return nil, err
	}
	for k, vals := range c.headers {
		for _, v := range vals {
			log.Println(k, v)
			r.Header.Add(k, v)
		}
	}

	if intercept != nil {
		intercept(r)
	}

	return c.c.Do(r)
}
